package vcp.client.GUI.mvc.view;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import org.joda.time.DateTime;

import vcp.client.GUI.mvc.view.addons.UpperToolBar;
import vcp.client.interfaces.delegates.IApplicationWindowDelegate;
import vcp.client.interfaces.delegates.IControllerViewDelegate;
import vcp.enums.Screen;

/**
 * <p>
 * user interface root view class
 * </p>
 * 
 * @author VCP team
 * 
 */
public class UIRootView extends JFrame
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private IControllerViewDelegate controllerDelegate;

	/**
	 * setter
	 * 
	 * @param controllerDelegate
	 */
	public void setControllerDelegate ( IControllerViewDelegate controllerDelegate )
	{
		this.controllerDelegate = controllerDelegate;
		this.toolBarView.setControllerDelegate(this.controllerDelegate);
	}

	private IApplicationWindowDelegate applicationWindowDelegate;

	/**
	 * setter
	 * 
	 * @param applicationWindowDelegate
	 */
	public void setApplicationWindowDelegate ( IApplicationWindowDelegate applicationWindowDelegate )
	{
		this.applicationWindowDelegate = applicationWindowDelegate;
	}

	private UpperToolBar toolBarView;

	/**
	 * constructor
	 */
	public UIRootView ()
	{
		super("VCP");
		this.setResizable(false);

		this.setupLayout();
		this.setupListeners();
	}

	/**
	 * sets application look and feel
	 */
	private void setApplicationLookAndFeel ()
	{
		try
		{
			UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
		}
		catch ( ClassNotFoundException
				| InstantiationException
				| IllegalAccessException
				| UnsupportedLookAndFeelException e )
		{
		}
	}

	/****************************************************************************************************************************
	 *** Public methods ***
	 ****************************************************************************************************************************/
	/**
	 * Present error message to user
	 * 
	 * @param questionMessage
	 *            - message to present to user
	 */
	public boolean showQuestion ( String questionMessage )
	{
		int dialogResult = JOptionPane.showConfirmDialog(this, questionMessage, "Question", JOptionPane.YES_NO_OPTION);
		boolean result = false;
		if ( dialogResult == JOptionPane.YES_OPTION )
		{
			result = ! result;
		}

		return result;
	}

	/**
	 * displays warning message pop up
	 * 
	 * @param warningMessage
	 */
	public void showWarning ( String warningMessage )
	{
		JOptionPane.showMessageDialog(this, warningMessage, "Warning", JOptionPane.WARNING_MESSAGE);
	}

	/**
	 * displays error message pop up
	 * 
	 * @param errorMessage
	 */
	public void showError ( String errorMessage )
	{
		JOptionPane.showMessageDialog(this, errorMessage, "Error", JOptionPane.ERROR_MESSAGE);
	}

	/**
	 * displays information message
	 * 
	 * @param informationMessage
	 */
	public void showInformation ( String informationMessage )
	{
		JOptionPane.showMessageDialog(this, informationMessage, "Information", JOptionPane.INFORMATION_MESSAGE);
	}

	/**
	 * method adds view to screen
	 * 
	 * @param comp
	 * @param constraints
	 */
	public void addView ( JComponent comp, Object constraints )
	{
		comp.setPreferredSize(new Dimension(this.getWidth(), this.getHeight() - 100));
		this.getContentPane().add(comp, constraints);

		this.reDrawScreen();
	}

	/**
	 * method removes view from screen
	 * 
	 * @param view
	 */
	public void removeView ( UIAbstractView view )
	{
		this.getContentPane().remove(view);
	}

	/**
	 * method updates screen name
	 * 
	 * @param name
	 */
	public void updateScreenName ( Screen name )
	{
		this.toolBarView.updateScreenName(name);

		boolean isDemoScreen = name == Screen.DEMO;
		this.toggleToolBarBackOption( ! isDemoScreen);
	}

	/**
	 * method enables displaying connection label on tool bar
	 * 
	 * @param connected
	 */
	public void setToolBarConnectionDisplayLabelEnable ( boolean connected )
	{
		this.toolBarView.setToolBarConnectionDisplayLabelEnabled(connected);
	}

	/**
	 * method resets client clock
	 */
	public void resetClientClock ()
	{
		this.toolBarView.resetClientClock();
	}

	/**
	 * method sets back option in tool bar
	 * 
	 * @param status
	 */
	public void toggleToolBarBackOption ( boolean status )
	{
		this.toolBarView.toggleDemoOption(status);
	}

	/**
	 * method adds given components to tool bar
	 * 
	 * @param items
	 */
	public void addComponentsToToolBar ( ArrayList <JComponent> items )
	{
		this.toolBarView.addToolBarItems(items);
	}

	/**
	 * method removes given components from tool bar
	 * 
	 * @param items
	 */
	public void removeComponentsFromToolBar ( ArrayList <JComponent> items )
	{
		this.toolBarView.removeToolBarItems(items);
	}

	/**
	 * method updates current time
	 * 
	 * @param clientTime
	 */
	public void updateCurrentTime ( DateTime clientTime )
	{
		this.toolBarView.updateTime(clientTime);
	}

	/****************************************************************************************************************************
	 *** Private methods ***
	 ****************************************************************************************************************************/
	/**
	 * sets up listeners
	 */
	private void setupListeners ()
	{
		this.setupWindowsEvents();
	}

	/**
	 * sets up layout
	 */
	private void setupLayout ()
	{
		this.setApplicationLookAndFeel();
		this.setSize(new Dimension(1024, 768));
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		this.toolBarView = new UpperToolBar();
		this.toolBarView.setPreferredSize(new Dimension(this.getWidth(), 60));
		this.getContentPane().add(this.toolBarView, BorderLayout.NORTH);
	}

	/**
	 * <p>
	 * This method will be called <b><u>only</u></b> after replacement of inner
	 * views is finished
	 * </p>
	 * To allow correct redrawing on screen
	 */
	private void reDrawScreen ()
	{
		this.validate();
		this.repaint();
	}

	/****************************************************************************************************************************
	 *** Handling Events ***
	 ****************************************************************************************************************************/
	/**
	 * Handles preconditions and post conditions for application
	 * 
	 * @see java.awt.event.WindowAdapter
	 */
	private void setupWindowsEvents ()
	{
		this.addWindowListener(new WindowAdapter()
			{
				@Override
				public void windowClosing ( WindowEvent e )
				{
					if ( UIRootView.this.applicationWindowDelegate != null )
					{
						UIRootView.this.applicationWindowDelegate.onApplicationClose();
					}
				}
			});

	}

}
